package cn.com.ethos.search;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.log4j.PropertyConfigurator;
import org.apache.lucene.analysis.standard.StandardAnalyzer;

import cn.com.ethos.search.index.IndexFacade;


public class IndexMain {

	public static final int OPT_HELP    = 'h';
	public static final int OPT_OPERATE = 'o';
	public static final int OPT_CONFIG  = 'c';
	public static final int OPT_LOG4J   = 'l';
	public static final int OPT_DIR     = 'd';
	
	private static final String OP_INDEX    = "index";
	private static final String OP_DELETE   = "delete";
	private static final String OP_OPTIMIZE = "optimize";
	
	
	private static Options OPTIONS = new Options();
	
	static  {
		/*Option o = new Option(String.valueOf((char)OPT_OPERATE),true,"operation: index|optimize");
		o.setRequired(true);
		OPTIONS.addOption(o);*/
		
		OPTIONS.addOption(String.valueOf((char)OPT_OPERATE),true,"operation: index|optimize");
		OPTIONS.addOption(String.valueOf((char)OPT_CONFIG),true,"configuration file,default file is "+ Constants.CONFIG_PATH);
		OPTIONS.addOption(String.valueOf((char)OPT_LOG4J),true,"log4j configuration file path. default file is " + Constants.LOG_CONFIG);
		OPTIONS.addOption(String.valueOf((char)OPT_HELP),false,"print help information");
	}
	
	public static void main(String[] args) throws Exception{
		
		CommandLineParser parser = new GnuParser();
		CommandLine 	  cmd 	 = parser.parse(OPTIONS, args);
		
		Option[] options =  cmd.getOptions();
		String   config  = Constants.CONFIG_PATH, 
				 log     = Constants.LOG_CONFIG, 
				 operate = Constants.Empty;
				
		for(Option o : options ) {
			switch(o.getId()) {
				case OPT_HELP:
					if(cmd.hasOption((char)OPT_HELP)) help();
					continue;
				case OPT_OPERATE:
					operate = cmd.getOptionValue((char)OPT_OPERATE,Constants.Empty);
					if(!operate.equalsIgnoreCase(OP_INDEX) 
					&& !operate.equalsIgnoreCase(OP_OPTIMIZE)
					&& !operate.equalsIgnoreCase(OP_DELETE)) {
						printHelp();
						System.exit(1);
					}
					continue;
				case OPT_LOG4J:
					log  = cmd.getOptionValue((char)OPT_LOG4J,Constants.LOG_CONFIG);
					continue;
				case OPT_CONFIG:
					config = cmd.getOptionValue((char)OPT_CONFIG,Constants.CONFIG_PATH);
					continue;
			}
			
		}
		
		if(operate == Constants.Empty) {
			printHelp();
			System.exit(1);	
		}
		
		setupSetting4log(log);
		Properties prop = loadSetting4config(config);
		puts("Startup " + operate + "...");
		long start 	= System.currentTimeMillis();
		
		if (operate.equalsIgnoreCase(OP_INDEX)) {
			IndexFacade.index(prop, new StandardAnalyzer());
		} else if(operate.equalsIgnoreCase(OP_DELETE)) {
			//    java cn.ethos.search.IndexMain -o delete nid.txt
			//or
			//    echo 'cid:12' | java cn.ethos.search.IndexMain -o delete
			//
			//nid.txt contains terms will be deleted
			String file = cmd.getArgs().length>0 ? file = cmd.getArgs()[0] : null;
			IndexFacade.delete(prop,new StandardAnalyzer(),file);
		} else {
			IndexFacade.optimize(prop);
		}
		
		long end   = System.currentTimeMillis();
		puts("End " + operate + ",it takes " + (end-start) +" ms");
		System.exit(0);
	}
	
	private
	static void puts(String s) {
		System.out.println(s);
	}	
	static void help() {
		printHelp();
		puts(Constants.Empty);
		puts("version:" + Constants.VERSION);
		puts("Report bugs to <gaoxinzhao@ethos.com.cn>");
		System.exit(0);
	}
	static void printHelp() {
		puts(Constants.Empty);
		HelpFormatter formatter = new HelpFormatter();	
		formatter.setDescPadding(5);
		formatter.printHelp("java cn.com.ethos.search.IndexMain \r\n  if you want to get more information while drucene is indexing,please set log4j configuration file for your level \r\n",
				OPTIONS);
	}
	
	static void setupSetting4log(String log) {
		if (!new File(log).isFile()) {
			puts("Can not find the config file for log4j from " + log);
			printHelp();
			System.exit(1);
		} else {
			puts("Loading configuration file for log4j from " + log);
			PropertyConfigurator.configure(log);
		}
	}
	
	static Properties loadSetting4config(String config) 
			throws IOException,FileNotFoundException{
		
		Properties prop = new Properties();
		File file       = new File(config);
		
		if(!file.isFile()) {
			puts("Can not find the configuration file for indexer from " + config);
			printHelp();
			System.exit(1);
		} else {
			puts("Loading configuration file for indexer from " + config);
			prop.load(new FileInputStream(file));
		}		
		return prop;
	}
	

}
